#include "../Base.h"

bool CheckMask(PCH base,PCH pattern,PCH mask)
{
	for(;*mask;++base,++pattern,++mask)
	{
		if(*mask == 'x' && *base !=*pattern)
		{
			return false;
		}
	}

}

PVOID SearchPatter(PCH base,DWORD length,PCH pattern,PCH mask)
{
	length -= (DWORD)strlen(mask);
	for(DWORD i = 0;i<length;i++){

		PVOID addr = &base[i];
		if(CheckMask((PCH)addr,pattern,mask))
		{
			return addr;
		}

	}
	return NULL;
}

bool CheckPatterFuzzy(PCH base, PCH pattern, ULONG_PTR size)
{
	for(;*pattern&&size;++base,++pattern,--size)
	{
		if(*pattern !=  '*' && *base != *pattern)
		return false;
	}
	return true;
}
PVOID SearchPatterFuzzy(PCH base, DWORD length, PCH pattern,ULONG_PTR size)
{
	length -= strlen(pattern);
	for(DWORD i = 0;i < length;i++)
	{
		PVOID addr = &base[i];
		if(CheckPatterFuzzy((PCH)addr,pattern,size))
		{
			return addr; 
		}
	}
	return NULL;
}



ULONG64 wpoff()
{
    _disable();
    ULONG64 mcr0 = __readcr0();
    __writecr0(mcr0 & (~0x10000));
    return mcr0;
}

VOID wpOn(ULONG64 old)
{
    __writecr0(old);
    _enable();
}



NTSTATUS
NTAPI
NtProtectVirtualMemory(
    __in HANDLE ProcessHandle,
    __inout PVOID* BaseAddress,
    __inout PSIZE_T RegionSize,
    __in ULONG NewProtect,
    __out PULONG OldProtect
) {

    typedef
        NTSTATUS
        (NTAPI
            * pfnZwProtectVirtualMemory)(
                __in HANDLE ProcessHandle,
                __inout PVOID* BaseAddress,
                __inout PSIZE_T RegionSize,
                __in ULONG NewProtect,
                __out PULONG OldProtect
                );
    static pfnZwProtectVirtualMemory ZwProtectVirtualMemoryFunc = NULL;
    if (!ZwProtectVirtualMemoryFunc) {

        UNICODE_STRING funName;
        RtlInitUnicodeString(&funName, L"ZwIsProcessInJob");
        PUCHAR funAddress = (PUCHAR)MmGetSystemRoutineAddress(&funName);
        if (!funAddress) {
            return STATUS_UNSUCCESSFUL;
        }
        if (funAddress) {
            funAddress += 20;
            for (int i = 0; i < 100; i++) {
                if (funAddress[i] == 0x48 && funAddress[i + 1] == 0x8B && funAddress[i + 2] == 0xc4) {
                    ZwProtectVirtualMemoryFunc = (pfnZwProtectVirtualMemory)(funAddress + i);
                    break;
                }
            }
        }

    }

    if (ZwProtectVirtualMemoryFunc) {

        return ZwProtectVirtualMemoryFunc(ProcessHandle, BaseAddress, RegionSize, NewProtect, OldProtect);

    }

    return STATUS_NOT_IMPLEMENTED;


}